package com.blockmeta.bbs.immodule.corebean;

import android.os.Handler;

import com.blockmeta.bbs.baselibrary.utils.TimeUtil;
import com.blockmeta.bbs.immodule.corebean.Impl.ImMetaManager;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


/**
 * todo 优化思路，可以采用小顶堆存储需要执行的消息的任务队列超时执行时间，这样每次不需要1秒循环一次，
 * 只需要取小顶堆的头部获取需要等待的时间，等时间到的时候取出顶进行处理
 * add 和 remove堆中元素，需要重新堆化。
 */
public class WaitSendQueue
{
	protected ConcurrentHashMap<String, Packet>	m_mapPacket;
	protected Handler 			m_hanlder;
	protected ArrayList<Packet> m_arTimeoutPacket;
	protected int m_nTimeout = 0;
	protected ImMetaManager m_connManager;

	public WaitSendQueue(ImMetaManager mgr)
	{
        m_hanlder   = new Handler();
		m_mapPacket = new ConcurrentHashMap<String, Packet>();
		m_arTimeoutPacket = new ArrayList<Packet>();

		m_connManager = mgr;
	}
	
	protected void clear()
	{
		m_mapPacket.clear();
	}
	
	protected Runnable	m_run = new Runnable() 
	{

		@Override
		public void run() 
		{			
			Iterator iter = m_mapPacket.entrySet().iterator();
			
			while(iter.hasNext())
			{
				Map.Entry pairs = (Map.Entry)iter.next();
				Packet pkt = (Packet) pairs.getValue();
				
				long interval = TimeUtil.getSeconds() - pkt.m_lTimeStamp;
					
				if (interval >= m_nTimeout)
				{
					iter.remove();
					m_arTimeoutPacket.add(pkt);
				}
			}
						
			if (m_mapPacket.size() > 0)
			{
				m_hanlder.postDelayed(this, 1000);
			}
			
			if (m_arTimeoutPacket.size() > 0)
			{
				for (Packet pkt : m_arTimeoutPacket)
				{
					if (pkt.m_listener != null)
					{
						pkt.m_listener.onTimeout(pkt.mUuid);
					}					
				}
				m_arTimeoutPacket.clear();
			}
		}		
	};


	public void addPacket(String uuid, IWaitListener listener)
	{
		if (m_nTimeout == 0)
		{
			//默认15m超时
			m_nTimeout = 15000 / 1000;
		}
		
		Packet packet = new Packet(uuid, listener);
		
		if (m_mapPacket.size() == 0)
		{
			m_hanlder.postDelayed(m_run, 1000);			
		}
		
		m_mapPacket.put(uuid, packet);
	}
	
	public void checkUpdate(String uuid)
	{		
		if (m_mapPacket.size() == 0)
			return;

		Iterator iter = m_mapPacket.entrySet().iterator();
		
		while(iter.hasNext())
		{
			Map.Entry pairs = (Map.Entry)iter.next();
			Packet waitPkt = (Packet) pairs.getValue();
			

				if (waitPkt.mUuid.equals(uuid))
				{
					if (waitPkt.m_listener != null)
					{
						iter.remove();					
						waitPkt.m_listener.onStatusOK(uuid);
					}
					break;
				}					

		}
	}



	public void closeConnection() {
	    clear();
	}

	public static class Packet
	{
		public String mUuid;
		public long			m_lTimeStamp;
		public IWaitListener m_listener;
		
		public Packet(String uuid, IWaitListener listener)
		{
			mUuid = uuid;
			m_listener = listener;
			m_lTimeStamp = TimeUtil.getSeconds();
		}
	}
	
	public interface IWaitListener
	{
		void onStatusOK(String uuid);
		void onTimeout(String uuid);
	}
}
